/**
 * @file color_print.c
 * @author Linquan  
 * @brief 
 * @version 1.0
 * @date 2024-06-18
 * 
 * @copyright Copyright (c) 2024
 * 
 * history:
 *      2024-12-6:
 *      彩色打印增加支持符号： %#x 、%#X
 * 
 */

#include "color_print.h"


#include <stdarg.h>
#include <time.h>
#include <sys/time.h>


void color_printf(const char* color, const char* format, ...) 
{
    va_list args;
    char hex_0X_flag = 0;

    va_start(args, format);

    while (*format != '\0') 
    {
         // 判断 #后的是不是X 或 x
        if(hex_0X_flag == 1)
        {
            if (*format == 'X')
            {
                hex_0X_flag = 0;
                int value = va_arg(args, int);
                printf("%s%X%s",  color, value, RESET);
            }
            else if (*format == 'x')
            {
                hex_0X_flag = 0;
                int value = va_arg(args, int);
                printf("%s%x%s",  color, value, RESET);
            }      
        }
        else if (*format == '%') 
        {
            format++; // 移动到占位符的下一个字符

            if (*format == 'd') {
                int value = va_arg(args, int);
                printf("%s%d%s", color, value, RESET);
            }else if (*format == 'x') {
                int value = va_arg(args, int);
                printf("%s%x%s",  color, value, RESET);
            } 
            else if (*format == 'X') {
                int value = va_arg(args, int);
                printf("%s%X%s",  color, value, RESET);
            } 
            else if (*format == '#' ) {
                const char* second_char  = format;  
                int value =  *(++second_char);    
                if((value == 'X') ||(value == 'x'))
                {
                    // printf("second %d \n", *second_char);
                    hex_0X_flag = 1;
                     printf("%s0X%s",  color, RESET);
                }      
            } 
             else if (*format == 'f') {
                double value = va_arg(args, double);
                printf("%s%f%s",  color, value, RESET);
            } else if (*format == 's') {
                char* value = va_arg(args, char*);
                printf("%s%s%s", color, value, RESET);
            } else if (*format == 'c') {
                int value = va_arg(args, int);
                printf("%s%c%s", color, value, RESET);
            } else 
            {
                printf("Unsupported format specifier: %c", *format);
            }
        }     
        else 
        {
            printf("%s%c%s", color, *format, RESET);
        }

        format++; // 移动到下一个字符
    }

    va_end(args);
}



static char const *get_base_file_name(char const *path)
{
  char const *file_name = path, *curr_str = path;
  while (curr_str && '\0' != *curr_str)
  {
    if ('/' == *curr_str)
      file_name = ++curr_str;
    else
      ++curr_str;
  }
  return file_name;
}



/**
 * @brief  printf current function's file name .
 * 
 * @param __file__ 
 */
void current_file(const char* _file_)
{
    YELLOW_PRINT( "[info]: ");
    CYAN_PRINT("file = %s .\n", get_base_file_name(_file_));
}



/**
 * @brief  printf current function's line .
 * 
 * @param _line_ 
 */
void current_line(int _line_)
{
    YELLOW_PRINT("[info]: ");
    CYAN_PRINT("line = %d . \n", _line_);
}

/**
 * @brief printf current function's name .
 * 
 * @param _function_ 
 */
void current_function(const char* _function_)
{
    YELLOW_PRINT("[info]: ");
    CYAN_PRINT("function: %s . \n", _function_);
}



/**
 * @brief printf current time and date
 * 
 * @param _time_ 
 * @param _data_ 
 */
void current_time_second()
{
    time_t current_timer;
    char *candlt;
    current_timer = time(NULL);
    candlt = ctime(&current_timer);
    YELLOW_PRINT("[info]: ");
    B_GREEN_PRINT("current time second: %s\n", candlt);
}

/**
 * @brief 获取时间，精确到微妙
 * 
 */
void current_time_us()
{
     struct timeval current_timer;
  
    gettimeofday(&current_timer, NULL);

    YELLOW_PRINT("[info]: ");
    B_GREEN_PRINT("current second: %d, us:%d\n", current_timer.tv_sec, current_timer.tv_usec);
}


void assert_failed(const char* _file_, const char* _function_, int _line_)
{
    B_CYAN_PRINT("    File:     ");   YELLOW_PRINT("%s \n", get_base_file_name(_file_));
    B_CYAN_PRINT("    Function: ");   YELLOW_PRINT("%s \n", _function_);
    B_CYAN_PRINT("    Line:     ");   YELLOW_PRINT("%d \n", _line_);
}


/** error print used */

void file_name_print(const char* _file_)
{
  B_BLUE_PRINT("File name: %s \n", get_base_file_name(_file_));
}


void line_print(int _line_)
{
  B_BLUE_PRINT("Line: %d \n", _line_);
}





